﻿using FingerTip.Framework.DependencyResolver;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace FingerTip.Framework.Queries
{
    public class QueryDispatcher:IQueryDispatcher
    {
        private readonly IResolver resolver;
        public QueryDispatcher(IResolver resolver)
        {
            this.resolver = resolver;
        }

        public TResult Dispatch<TQuery,TResult>(TQuery query) where TQuery : IQuery
        {
            var queryHandler = GetHandler<IQueryHandler<TQuery, TResult>, TQuery>(query);
            return queryHandler.Retrieve(query);
        }

        public async Task<TResult> DispatchAsync<TQuery, TResult>(TQuery query) where TQuery : IQuery
        {
            var queryHandler =  GetHandler<IQueryHandlerAsync<TQuery, TResult>, TQuery>(query);
            return await queryHandler.RetrieveAsync(query);
        }


        public THandler GetHandler<THandler, TQuery>(TQuery query) where TQuery : IQuery
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }
            var queryHandler = resolver.Resolve<THandler>();
            if (queryHandler == null)
            {
                throw new Exception($"No handler found for query '{query.GetType().FullName}'");
            }

            return queryHandler;
        }
    }
}
